/********************************************************************************
  Header comune a tutte le componenti del programma, contiene definizioni di
  tipi e macro di utilizzo comune come il tipo bool, le funzioni di allocazione
  e deallocazione della memoria (new, delete..) e le funzioni di segnalazione
  degli errori
********************************************************************************/

#ifndef COMMON_H
#define COMMON_H

#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string.h>

//#define DEBUG
//#define NAME_THREAD

/* time defines */
#define NANOSEC 1
#define MICROSEC 1000*NANOSEC
#define MILLISEC 1000*MICROSEC
#define SEC 1000*MILLISEC

typedef enum {false, true} bool;

#define new(type) (type *) malloc(sizeof(type))
#define new_vector(type, dim) (type *) malloc(sizeof(type)*dim)
#define delete(var) free(var)

#define streq(a,b) (strcmp(a,b) == 0)

#define throw_msg(msg) {			\
    fprintf(stdout, msg);			\
}

#define throw_error(funcName, errMsg) {					\
    fprintf(stderr, "An error occurred in %s: %s\n\t", funcName, errMsg); \
    perror("\tPERROR");							\
    exit(-1);								\
  }

#define throw_cond_error(cond, funcName, errMsg) {			\
    if (cond) {								\
      fprintf(stderr, "An error occurred in %s: %s\n\t", funcName, errMsg); \
      perror("\tPERROR");							\
      exit(-1);								\
    }									\
  }

#ifdef DEBUG
#define debug(msg){				\
    fprintf(stderr, msg);			\
    sleep(2);					\
  }
#else
#define debug(msg) {}
#endif

#ifdef DEBUG
#define debugInt(msg, vname, v){			\
    fprintf(stderr, "%s; %s = %d\n", msg, vname, v);	\
    sleep(2);						\
  }
#else
#define debugInt(msg, vname, v) {}
#endif

#ifdef NAME_THREAD
#define track_thread(msg){						\
    fprintf(stdout, "%s, thread_id = %lu\n", msg, (unsigned)pthread_self()); \
  }
#else
#define track_thread(msg) {}
#endif


#endif /* COMMON_H */
